Skip to content

fix(create,stream,lib): correct stream rate, recipient guard, stream ID, and deposit total - #379

Merged
Jaydbrown merged 2 commits into
conduit-protocol:mainfrom
Akanimoh12:fix/create-stream-rate-precision-and-total-deposited
Aug 30, 2026
Merged

fix(create,stream,lib): correct stream rate, recipient guard, stream ID, and deposit total#379
Jaydbrown merged 2 commits into
conduit-protocol:mainfrom
Akanimoh12:fix/create-stream-rate-precision-and-total-deposited

Conversation

@Akanimoh12

Copy link
Copy Markdown
Contributor

Summary

Fixes four assigned stream-flow bugs:

Tests

Updated the affected Soroban, factory, stream, and create-page tests. Local test execution was unavailable because dependencies were not installed in the workspace.

Akanimoh12 and others added 2 commits August 27, 2026 23:40
…cipient check, surface create_stream's returned stream id, and fix total-deposited calc

Fixes four related bugs in the create-stream and stream-detail flows:

- conduit-protocol#364: the rate preview used float math (parseFloat(deposit) * 10 **
  tokenDecimals / duration) which loses precision for large deposits /
  high-decimal tokens and rounds where the actual submitted rate
  (depositStroops / BigInt(durationSeconds)) truncates. The preview now
  runs the same toStroops + truncating BigInt division pipeline as
  onSubmit, so the displayed rate always matches what gets signed.

- conduit-protocol#363: the submit button was not disabled while recipientStatus ===
  'checking', so a user could submit within the 600ms debounce + RPC
  window and bypass the not-found guard entirely. The button is now also
  disabled while checking, and onSubmit hard-blocks on 'checking' too.

- conduit-protocol#362: invokeContract() discarded the confirmed transaction's
  returnValue, so DripFactory::create_stream's assigned stream_id could
  never be surfaced to callers. invokeContract() now resolves to
  { hash, returnValue }, and lib/factory.ts createStream() decodes the
  u64 stream_id from it and returns { hash, streamId }. The create page
  now deep-links straight to the new stream when the id is available,
  falling back to /streams only when it isn't.

- conduit-protocol#361: the stream detail page rendered info.withdrawn + withdrawable
  (the amount already streamed) as 'Total deposited', excluding the
  not-yet-streamed principal still escrowed in the DripStream contract.
  For fixed-duration streams this is now computed as
  ratePerSecond * (endTime - startTime), the actual amount escrowed at
  creation.

Updated unit tests across lib/soroban.ts, lib/factory.ts, lib/stream.ts,
and app/create to match the new return shapes and guard behaviour.
@drips-wave

drips-wave Bot commented Aug 30, 2026

Copy link
Copy Markdown

@Akanimoh12 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Jaydbrown
Jaydbrown merged commit 354691f into conduit-protocol:main Aug 30, 2026
1 of 3 checks passed
mhikel66 added a commit to mhikel66/streamFi-app that referenced this pull request Aug 30, 2026
…col#379 merge

The conduit-protocol#379 merge left lib/soroban.ts non-compiling: invokeContract's body
had a stray fragment of an inlined poll loop (referencing an out-of-scope
`status`, plus a leftover `}, { context, signal })` from the withRetry
call) wedged between the submit step and the real
`return pollForConfirmation(...)`. tsc bailed with 'Declaration or
statement expected', which is why every downstream CI job was red even
past npm ci.

- invokeContract: drop the mangled fragment; it already returned
  pollForConfirmation(hash, ...).
- pollForConfirmation: finish the conduit-protocol#362 change it was mid-refactor on —
  return InvokeContractResult ({ hash, returnValue }) instead of a bare
  string, capturing status.returnValue on SUCCESS so callers like
  createStream can read the assigned stream_id.
- Export resetFeeStatsCache() and call it in soroban-pipeline.test's
  beforeEach — the module-level fee cache (intentionally shared across
  invokeContract calls) was leaking between test cases.
- Update soroban-pipeline / stream / tokens tests for the new
  InvokeContractResult shape and the flags-first field parsing order.
therealjhay added a commit to therealjhay/streamFi-app that referenced this pull request Aug 30, 2026
…solate test state

soroban.ts was broken since conduit-protocol#379: duplicated poll logic with a stray
status check left the file syntactically invalid and pollForConfirmation
still returned string instead of InvokeContractResult. Make poll return
{ hash, returnValue } on SUCCESS and { hash } on pending timeout so
create_stream's stream_id surfaces correctly, and clean up the stray
block. Also clear the inclusion-fee cache on resetServer / via
__clearFeeStatsCache so fee-stats tests don't leak cached p70 across
cases.

Tests: update soroban-pipeline mocks to expect object shape, fix
tokens.test mock type, add checkAllowance RPC-failure distinguishing
test, fix stream.test missing-field order, and mock
checkRecipientExists in create/page tests with debounce-aware waits.
Jaydbrown pushed a commit that referenced this pull request Aug 30, 2026
* fix(tokens): distinguish RPC failure from insufficient allowance in checkAllowance

checkAllowance previously swallowed getAllowance RPC/network errors and
returned { hasAllowance: false }. The create-stream flow keys off
hasAllowance to decide whether to prompt an SEP-41 approve(), so a
transient hiccup incorrectly triggered an extra signed transaction and
fee even when allowance was already sufficient.

Return { hasAllowance: undefined, error } on failure so callers can
distinguish 'checked, insufficient' (hasAllowance === false) from
'couldn't check' (hasAllowance === undefined) and retry the read
instead of defaulting to needs-approval. Update AllowanceResult docs
accordingly.

* fix(soroban,tests): restore invokeContract returnValue plumbing and isolate test state

soroban.ts was broken since #379: duplicated poll logic with a stray
status check left the file syntactically invalid and pollForConfirmation
still returned string instead of InvokeContractResult. Make poll return
{ hash, returnValue } on SUCCESS and { hash } on pending timeout so
create_stream's stream_id surfaces correctly, and clean up the stray
block. Also clear the inclusion-fee cache on resetServer / via
__clearFeeStatsCache so fee-stats tests don't leak cached p70 across
cases.

Tests: update soroban-pipeline mocks to expect object shape, fix
tokens.test mock type, add checkAllowance RPC-failure distinguishing
test, fix stream.test missing-field order, and mock
checkRecipientExists in create/page tests with debounce-aware waits.
Jaydbrown added a commit to mhikel66/streamFi-app that referenced this pull request Sep 1, 2026
The conduit-protocol#379-merge breakage this PR set out to repair (lib/soroban.ts
invokeContract, app/create timeout helper) is already fixed on main via
later merges, so every conflicting hunk resolves to main's version and
the merge is a no-op.
Jaydbrown added a commit that referenced this pull request Sep 1, 2026
…epair

fix: repair lib/soroban.ts + app/create mangled by the #379 merge
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment